<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | 用户授权
// +----------------------------------------------------------------------

namespace app\home\controller;

use app\common\model\Config;
use app\common\model\Oauth;
use app\common\model\User;
use app\common\model\UserDevice;
use app\common\model\VerificationCode;
use helper\tencent\QQ;
use think\captcha\facade\Captcha;
use think\exception\ValidateException;
use think\facade\View;

class AuthController extends HomeBaseController
{
    /**
     * @OA\Get(path="/index",tags={"用户认证"},summary="验证码",
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function verification()
    {
        return Captcha::create();
    }

    /**
     * @OA\Post(path="/index",tags={"用户认证"},summary="验证码",
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="手机", property="mobile", type="string")
     *           @OA\Property(description="邮箱", property="email", type="string")
     *          )
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function captcha()
    {
        $param = $this->request->param();
        if (isset($param['mobile'])) {
            $res = VerificationCode::setCode($param['mobile']);
            if ($res['code']) {
                $this->error("发送失败," . $res['message']);
            }
            $this->success($res['message']);
        }

        if (isset($param['email'])) {
            // 验证码
            $code = rand(100000, 999999);
            session('code', $code);
            $site_name   = $this->website['site_name'];
            $site_domain = $this->website['domain'];
            $content     = '<p>亲爱的' . $site_name . '用户：<br><br>您好！您正在进行注册' . $site_name . '账号，本次邮件验证码为：</p>
                <h1><strong>' . $code . '</strong></h1>
                <p>
                为了您的账号安全，请尽快完成验证。
                <br>如果您没有提交过注册' . $site_name . '账号的请求，请忽略此邮件。此邮件由系统发送，请勿直接回复。<br>
                <br>' . $site_name . '团队
                <br><a href="' . $site_domain . '" rel="noopener" target="_blank">' . $site_domain . '</a>
                </p>';
            $result      = Config::mail($param['email'], $site_name . '账号注册验证', $content);
            if (!$result['code']) {
                $this->success('发送成功');
            }
            $this->error('发送失败, ' . $result['message']);
        }
    }

    /**
     * 注册
     */
    public function register()
    {
        if ($this->request->isPost()) {
            $post = $this->request->post();
            try {
                $this->validate($post, 'app\common\validate\Register');
            } catch (ValidateException $e) {
                $this->error($e->getError());
            }

            if ($post['code'] != session('code')) {
                $this->error('验证码错误');
            }

            //注册入库
            $app                = $this->auth()->setApp();
            $data['app_id']     = $app['appId'];
            $data['app_secret'] = $app['appSecret'];
            $data['email']      = $post['email'];
            $data['username']   = $post['username'];
            $data['password']   = $post['password'];
            $data['last_time']  = $data['email_verified_at'] = date('Y-m-d H:i:s');
            $data['last_ip']    = $this->request->ip();
            $user               = User::create($data);
            $this->success('注册成功!', $user, 'login');
        }
        return View::fetch('user/register');
    }

    /**
     * 登录
     */
    public function login()
    {
        if (auth()->check()) {
            return redirect('user');
        }
        if ($this->request->isPost()) {
            $param = $this->request->param();
            try {
                $this->validate($param, 'app\common\validate\Login');
            } catch (ValidateException $e) {
                $this->error($e->getError());
            }
            $remember = isset($param['remember']);
            $field    = 'username';
            if (filter_var($param['username'], FILTER_VALIDATE_EMAIL)) {
                $field = 'email';
            }
            if ($this->auth()->attempt($param, $remember, $field)) {
                $user = $this->auth()->user();
                // 设备
                if (empty($param['device_id'])) {
                    UserDevice::assign($user->id(), $param);
                }
                // 分发UserLogin事件
                event('UserLogin', $user);
                return $this->success('登入成功', ['access_token' => $user->remember_token], '/user');
            }
            return $this->error('账号或密码错误');
        }
        return View::fetch('user/login');
    }

    /**
     * 退出
     * @return \think\response\Redirect
     */
    public function logout()
    {
        $this->auth()->logout();
        return redirect('login');
    }

    /**
     * 忘记密码
     */
    public function forgetPassword()
    {
        if ($this->request->isPost()) {
            $param = $this->request->param();

            if (empty($param["email"])) {
                $this->error('邮箱不能为空');
            }

            $user = User::where('email', $param["email"])->find();
            if (!$user) {
                $this->error('用户不存在');
            }

            $site_name   = $this->website['site_name'];
            $site_domain = $this->website['domain'];

            // 验证码
            $reset_password_token = uniqid();
            session('reset_password_email', $param['email']);
            session('reset_password_token', $reset_password_token);
            $url     = $site_domain . "/reset?email={$param['email']}&reset_password_token=$reset_password_token";
            $content = '<div class="container">
                <div class="panel">
                    <div class="panel-header">密码重置</div>
                    <div class="panel-body">
                        <p>
                            您好 <a href="mailto:' . $param['email'] . '" rel="noopener" target="_blank">' . $param['email'] . '</a>！
                        </p>
                        <p>您已经请求了重置密码，可以点击下面的链接来重置密码。</p>
                        <p><a href="' . $url . '" rel="noopener" target="_blank">' . $url . '</a></p>
                        <p>如果您没有请求重置密码，请忽略这封邮件。</p>
                        <p>在您点击上面链接修改密码之前，您的密码将会保持不变。</p>
                    </div>
                </div>
            </div>';
            $result  = Config::mail($param['email'], $site_name . '重置密码信息', $content);
            if (!$result['code']) {
                $this->success('发送成功，请到邮件查看');
            }
            $this->error('发送失败');
        }
        return View::fetch('user/forget');
    }

    /**
     * @OA\Post(path="/reset_password",tags={"用户认证"},summary="重置密码",
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="密码", property="password", type="string", default=""),
     *           @OA\Property(description="确认密码", property="password_confirm", type="string", default=""),
     *           required={"password", "password_confirm"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function resetPassword()
    {
        if ($this->request->isPost()) {
            $param = $this->request->param();

            $email = session('reset_password_email');
            $token = session('reset_password_token');
            if ($param['email'] != $email || $param['reset_password_token'] != $token) {
                $this->error('非法访问');
            }

            //密码长度不能低于6位
            if (strlen(trim($param["password"])) < 6) {
                $this->error('密码长度不能低于6位');
            }
            if ($param["password"] !== $param["password_confirm"]) {
                $this->error('两次输入的密码不一致');
            }
            $user = User::field('id,email')->where('email', $param["email"])->find();
            if (!$user) {
                $this->error('用户不存在');
            }
            $user->password = $param["password"];
            $res            = $user->save();
            if ($res) {
                $this->success('密码重置成功', '', '/login');
            }
            $this->error('密码重置失败');
        }
        return View::fetch('user/reset');
    }

    /**
     * 确认密码
     * @return void
     */
    public function confirmPassword()
    {

    }

    /**
     * 三方登录
     * @return string
     */
    public function oauth()
    {
        $url = Oauth::alipay()->getCode($this->website['domain'] . '/oauth');
        View::assign('alipay', $url);
        return View::fetch('template/oauth');
    }

    public function qqLogin()
    {
        $return_url = empty($_GET['return_url']) ? exit('回调地址不可为空！') : $_GET['return_url'];
        $token = empty($_GET['token']) ? exit('Token不可为空！') : $_GET['token'];
        $config["callback"] = 'http://www.koock.cn/qqlogin/return.php?return_url=' . $return_url . '&token=' . $token;
        $QC = new QQ($config);
        $QC->login();
    }

    public function qqReturn()
    {
        $return_url = empty($_GET['return_url']) ? exit('回调地址不可为空！') : $_GET['return_url'];
        $token = empty($_GET['token']) ? exit('Token不可为空！') : $_GET['token'];
        $QC_config["callback"] = 'http://www.koock.cn/qqlogin/return.php?return_url=' . $return_url . '&token=' . $token;
        $QC = new QQ($QC_config);
        $access_token = $QC->callback();
        $openid = $QC->getOpenid($access_token);
        $url = $return_url . '?openid=' . $openid . '&token=' . $token;
        header("Location:$url");
    }
}